package ac.svn.accesscontrol.controller;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.swing.SwingUtilities;

import ac.notification.event.INotificationListener;
import ac.notification.event.NotificationEvent;
import ac.notification.manager.NotificationRegistrar;
import ac.svn.accesscontrol.manager.SVNInfoManager;
import ac.svn.accesscontrol.store.ISVNIdentifier;
import ac.svn.accesscontrol.store.ISVNItem;
import ac.svn.accesscontrol.ui.helper.ILister;

public class ListingController implements ISVNIdentifier, INotificationListener {

    private static ListingController listingController = new ListingController();
    
    private Map<String,Set<ILister>> 	contentListers;
    //private Map<String,Set<IListFilter>>	contentFilters;

    public static final String LOCATION = "LOCATION";
    public static final String GROUP	= "GROUP";
    public static final String USER 	= "USER";
    public static final String ACCESS 	= "ACCESS";

    private Set<String> notificationType = null;

    private ListingController()
    {
	this.contentListers = new HashMap<String, Set<ILister>>();

	notificationType = new HashSet<String>();
	notificationType.add(GROUP);
	notificationType.add(LOCATION);
	notificationType.add(USER);
	notificationType.add(ACCESS);
	NotificationRegistrar.registerListener(this);
    }


    public void registerListerForNotifications(ILister contentLister, String notification)
    {
	if((null != contentLister))
	{
	    if(notificationType.contains(notification))
	    {
		//Get list of Listers who are already present for mentioned notification.
		Set<ILister> items = contentListers.get(notification);

		//If current lister is first to register for event, create set for same.
		if(null == items)
		{
		    items = new HashSet<ILister>();   
		}

		//Add new lister
		items.add(contentLister);

		//Update
		contentListers.put(notification, items);
	    }

	}
    }    

    /**
     * OVERRIDDEN SECTION
     * 
     * */
    @Override
    public Set<String> declaredSubscriptionSet() 
    {
	Set<String> subscriptions = new HashSet<String>();
	subscriptions.add(N_UPDATE_LISTINGS);
	return subscriptions;
    }

    @Override
    public void receiveEvent(NotificationEvent notificationEvent) 
    {
	String neId = notificationEvent.getPropertyIdentifier();
	if(neId.contains(N_UPDATE_LISTINGS))
	{
	    updateListingsHandler(notificationEvent);
	}
    }


    private void updateListingsHandler(final NotificationEvent notificationEvent) 
    {
	SwingUtilities.invokeLater(new Runnable() 
	{
	    @Override
	    public void run() 
	    {
		String listingType 		= (String) notificationEvent.getPropertyValue();
		Set<ILister> listers 		= contentListers.get(notificationEvent.getPropertyValue());
		Set<ISVNItem>	    listings	= null;

		if(USER.equalsIgnoreCase(listingType))
		{
		    listers = contentListers.get(USER);
		    listings = SVNInfoManager.getInfoManager().getAllUsers();
		}
		else if(GROUP.equalsIgnoreCase(listingType))
		{
		    listers = contentListers.get(GROUP);
		    listings = SVNInfoManager.getInfoManager().getAllGroups();
		} 
		else if(LOCATION.equalsIgnoreCase(listingType))
		{
		    listers = contentListers.get(LOCATION);
		    listings = SVNInfoManager.getInfoManager().getAllLocations();
		}   
		else if(ACCESS.equalsIgnoreCase(listingType))
		{
		    listers = contentListers.get(ACCESS);
		    String locationPath = (String) notificationEvent.getParameter(P_LOCATION);
		    listings = SVNInfoManager.getInfoManager().getAccessListing(locationPath);
		}
		
		for(ILister contentLister : listers)
		{
		    contentLister.listItems(listings);
		}		
	    }
	});	
    }


    /**
     * @return the listingController
     */
    public static ListingController getListingController() 
    {
        return listingController;
    }

}
